﻿#region LGPL
/************************************************************************************/
/* Fireball.Windows.Forms a controls library for windows forms
 * 
 * Copyright (C) 2009 Sebastian Faltoni
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the 
 * Free Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
 * for more details.
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, write to the Free Software Foundation, Inc., 59 
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * 
 * Signature of Sebastian Faltoni, 2 Febbraio 2009
 * Sebastian Faltoni, President of Orangebit
 * 
 ***********************************************************************************/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;

namespace Orangebit.Windows.Forms
{
    /// <summary>
    /// The ExplorerBarItem is a Control you should use as a Child Item of the ExplorerBar Control
    /// </summary>
    public class ExplorerBarItem : StackPanelItem
    {
        private string headerText = null;

        /// <summary>
        /// The Text to be shown on the Header
        /// </summary>
        public string HeaderText
        {
            get
            {
                return headerText;
            }
            set
            {
                headerText = value;
                this.Invalidate();
            }
        }

        /// <summary>
        /// Don't use this property directly, use Child instead, if your try
        /// to add multiple elements you will end with a fuzzy layout :)
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ControlCollection Controls
        {
            get
            {
                return base.Controls;
            }
        }

        /// <summary>
        /// The Child Control for this ExplorerBarItem, if you need to add more controls 
        /// just add a root Panel and add your children's to the new panel
        /// </summary>
        public Control Child
        {
            get
            {
                if (this.Controls.Count == 0)
                    return null;
                return this.Controls[0];
            }
            set
            {
                this.PerformLayout();
                this.Controls.Clear();
                this.Controls.Add(value);                
                this.Invalidate(true);
                this.ResumeLayout(true);
                value.SizeChanged += new EventHandler(value_SizeChanged);
            }
        }

        void value_SizeChanged(object sender, EventArgs e)
        {
            this.OnSizeChanged(EventArgs.Empty);
        }

        //private Color headerColor = Color.Empty;
        ///// <summary>
        ///// The Color that should be used for the header
        ///// </summary>
        //public Color HeaderColor
        //{
        //    get
        //    {
        //        return headerColor;
        //    }
        //    set
        //    {
        //        headerColor = value;
        //        this.Invalidate();
        //    }
        //}

        private Image headerImage = null;

        /// <summary>
        /// The Image to be shown on the Header, it must be of 32x32 pixels
        /// </summary>
        public Image HeaderImage
        {
            get
            {
                return headerImage;
            }
            set
            {
                if (value.Width != 32 && value.Height != 32)
                {
                    throw new Exception("Header Image Must be 32x32 in size.");
                }
                headerImage = value;
                this.PerformLayout();
                this.Invalidate();
            }
        }

        protected virtual IExplorerBarTheme Theme
        {
            get
            {
                if (this.DesignMode)
                    return new DefaultExplorerBarTheme();
                ExplorerBar explorerBar = this.Parent as ExplorerBar;
                if (explorerBar == null)
                    return null;
                return explorerBar.Theme;
            }
        }

        //public void SetDisplayRectangle(Rectangle displayRect)
        //{
        //    displayRectangle = displayRect;
        //}

        private bool isExpanded = true;
        private int oldHeight = 0;
        /// <summary>
        /// Get or Set if the item is Expanded
        /// </summary>
        public bool IsExpanded
        {
            get
            {
                return isExpanded;
            }
            set
            {
                isExpanded = value;

                if (!isExpanded)
                {
                    oldHeight = this.Height;
                    this.Height = this.Theme.GetCollapsedHeight(this);
                }
                else
                {
                    this.Height = oldHeight;
                }
                this.PerformLayout();
                this.Invalidate();
            }
        }




        public void Toogle()
        {
            this.IsExpanded = !this.isExpanded;
        }

        private bool isMouseOverHeader = false;
        public bool IsMouseOverHeader
        {
            get
            {
                return isMouseOverHeader;
            }
            private set
            {
                isMouseOverHeader = false;
                if (isMouseOverHeader)
                {
                    this.Cursor = Cursors.Hand;
                }
                else
                {
                    this.Cursor = Cursors.Default;
                }
                this.PerformLayout();
                this.Invalidate();
            }
        }

        protected override void OnMouseHover(EventArgs e)
        {
            if (CheckIsMouseOverHeader())
                this.IsMouseOverHeader = true;
            else
                this.IsMouseOverHeader = false;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            if (!CheckIsMouseOverHeader())
                this.IsMouseOverHeader = false;
            this.Invalidate();
        }

        private bool CheckIsMouseOverHeader()
        {
            Rectangle rc = new Rectangle(0, 0, this.Width, this.Theme.GetCollapsedHeight(this));
            var point = this.PointToClient(Cursor.Position);
            return rc.Contains(point);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if (this.Theme.GetToogleButtonArea(this).Contains(e.Location))
            {
                this.Toogle();
            }
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            //SetSizeByTheme();
            this.Theme.PaintExplorerItem(this, e);
        }

        public override void SetHeight(int h)
        {
            if (this.IsExpanded)
            {
                base.SetHeight(h);
                oldHeight = h;
            }
        }

        [DefaultValue(true)]
        public override bool Fit
        {
            get
            {

                if (!this.IsExpanded && this.StackPanel.Orientation == Orientation.Horizontal)
                    return false;
                return base.Fit;
            }
            set
            {
                base.Fit = value;
                this.PerformLayout();
                this.Invalidate();
            }
        }

        void ExplorerBarItem_ParentChanged(object sender, EventArgs e)
        {
            if (this.Parent != null && (this.Parent as ExplorerBar) != null)
            {
                this.Theme.OnExplorerBarItemSizeChanged(this);
                this.Refresh();
            }
        }

        //protected override void OnHandleCreated(EventArgs e)
        //{
        //    base.OnHandleCreated(e);
        //    if (this.Theme != null)
        //    {
        //        this.Theme.OnExplorerBarItemSizeChanged(this);
        //        this.Invalidate();
        //    }
        //}

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);

            if (this.StackPanel != null && this.StackPanel.Orientation == Orientation.Vertical)
                base.OnSizeChanged(e);
            SetSizeByTheme();
            this.Invalidate(true);
        }

        private void SetSizeByTheme()
        {
            if (this.Theme != null && this.IsHandleCreated)
                this.Theme.OnExplorerBarItemSizeChanged(this);
        }

        public ExplorerBarItem()
        {
            this.SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer
                    | System.Windows.Forms.ControlStyles.AllPaintingInWmPaint
                    | System.Windows.Forms.ControlStyles.SupportsTransparentBackColor
                    | System.Windows.Forms.ControlStyles.ResizeRedraw
                   | ControlStyles.UserMouse
                    | System.Windows.Forms.ControlStyles.UserPaint, true);
            this.BackColor = Color.Transparent;
            this.Margin = new Padding(10);
            this.ParentChanged += new EventHandler(ExplorerBarItem_ParentChanged);
            //  this.MinimumSize = new Size(100, 100);
        }        
    }
}
